<?
/*-- Project Introduce --*/


class JCAT_FSPackageFolder extends JCAT_FSPackageElement
{
	const XMLNODENAME = 'd' ;
	
	/**
	 * Description
	 *
	 * @access	public
	 * @param	$sPath
	 * @return	void
	 */
	public function JCAT_FSPackageFolder($sPath=null)
	{
		$this->sPath = $sPath ;
		if($sPath)
		{
			$this->SetName(basename($sPath)) ;
		}
	}
	
	/**
	 * Description
	 *
	 * @access	public
	 * @param	$aFolderDoc		SimpleXMLElement
	 * @static
	 * @return	void
	 */
	static public function CreateFromDoc(SimpleXMLElement $aFolderDoc)
	{
		
	}
		
	/**
	 * Description
	 *
	 * @access	public
	 * @param	$aIterator	JCAT_FSPackageFSOIterator
	 * @return	void
	 */
	public function SetupIterator(JCAT_FSPackageFSOIterator $aIterator)
	{
		$nIterFlg = $aIterator->GetIterFlag() ;
		if( $nIterFlg&JCAT_FSPackage::ITER_DIR )
		{
			$aIterator->AddFSOs($this->arrFolderChildren);
		}
		
		else if( $nIterFlg&JCAT_FSPackage::ITER_FILE )
		{
			$aIterator->AddFSOs($this->arrFileChildren);
		}
		
		else
		{
			$aIterator->AddFSOs($this->arrChildren);
		}
		
		// 递归下级目录
		foreach($this->arrFolderChildren as $aFolder)
		{
			$aFolder->SetupIterator($aIterator) ;
		}
	}
	
	/**
	 * Description
	 *
	 * @access	public
	 * @param	$aXMLDoc		SimpleXMLElement
	 * @return	void
	 */
	public function LoadFromXMLDoc(SimpleXMLElement $aXMLDoc)
	{
		$arrFolders = $aXMLDoc->xpath(JCAT_FSPackageFolder::XMLNODENAME) ;
		$arrFiles = $aXMLDoc->xpath(JCAT_FSPackageFile::XMLNODENAME) ;
		
		// 子目录
		foreach($arrFolders as $aFolderDoc)
		{
			// 创建子目录
			$aFolder = new self() ;
			$aFolder->SetName(strval($aFolderDoc['name'])) ;
			$this->Append($aFolder) ;
			
			// 递归下级
			$aFolder->LoadFromXMLDoc($aFolderDoc) ;
		}
		
		// 文件
		foreach($arrFiles as $aFileDoc)
		{
			// 创建子目录
			$aFile = new JCAT_FSPackageFile() ;
			$aFile->LoadFromXMLDoc($aFileDoc) ;
			
			$this->Append($aFile) ;
		}
		
	}

	/**
	 * Description
	 *
	 * @access	public
	 * @return	string
	 */
	public function MakeXML($bOnlyChildren=false)
	{
		$sXML = "" ;
		
		if(!$bOnlyChildren)
		{
			$sFilename = $this->GetName() ;
			
			$sXML.= "<".self::XMLNODENAME ;
			$sXML.= " name=\"{$sFilename}\">" ;
		}
		
		// 下级目录
		foreach($this->arrFolderChildren as $aFolder)
		{
			$sXML.= $aFolder->MakeXML() ;
		}
		
		// 下级文件
		foreach($this->arrFileChildren as $aFile)
		{
			$sXML.= $aFile->MakeXML() ;
		}
		
		if(!$bOnlyChildren)
		{
			$sXML.= "</".self::XMLNODENAME.">" ;
		}
		
		return $sXML ;
	}
	
	/**
	 * Description
	 *
	 * @access	public
	 * @param	$sFilename
	 * @return	JCAT_FSPackageElement
	 */
	public function GetChild($sFilename)
	{
		return isset($this->arrChildren[$sFilename])? $this->arrChildren[$sFilename]: null ;
	}

	/**
	 * Description
	 *
	 * @access	public
	 * @param	$arrPath	array()
	 * @return	JCAT_FSPackageElement
	 */
	public function GetChildRecursion(array $arrPath)
	{
		$sName = array_shift($arrPath) ;
		if(!count($arrPath))
		{
			return $this->GetChild($sName) ;
		}
		
		else
		{
			$aChildFolder = $this->GetChild($sName) ;
			if( $aChildFolder and ($aChildFolder instanceof self) )
			{
				return $this->GetChildRecursion($arrPath) ;
			}
			
			else 
			{
				return null ;
			}
		}
	}
	
	/**
	 * Description
	 *
	 * @access	public
	 * @param	$arrPath	array()
	 * @return	JCAT_FSPackageElement
	 */
	public function CreateChildRecursion(array $arrPath,$bFolder=true)
	{
		$sName = array_shift($arrPath) ;
		
		// 创建
		if(!count($arrPath))
		{
			$aNewChild = $bFolder? new JCAT_FSPackageFolder() : new JCAT_FSPackageFile() ;
			$aNewChild->SetName($sName) ;
			
			$this->Append($aNewChild);
			
			return $aNewChild ;
		}
		
		// 递归
		else
		{
			$aChildFolder = $this->GetChild($sName) ;
			
			// 创建下级目录
			if( !$aChildFolder or !($aChildFolder instanceof self) )
			{
				$aChildFolder = new JCAT_FSPackageFolder() ;
				$aChildFolder->SetName($sName) ;
			
				$this->Append($aChildFolder);
			}
			
			// 递归创建
			if( !is_array($arrPath) or !count($arrPath) )
			{
				throw new JCAT_Exception(JCAT_Language::SentenceEx(
					'路径错误。%s'
					, 'JCAT', null, $arrPath
				)) ;
			}
			return $aChildFolder->CreateChildRecursion($arrPath,$bFolder) ;
		}
	}
	
	/**
	 * Description
	 *
	 * @access	public
	 * @return	void
	 */
	public function Append(JCAT_FSPackageElement $aChild)
	{
		$sFilename = $aChild->GetName() ;
		
		$this->arrChildren[$sFilename] = $aChild ;
		
		// 文件夹
		if( $aChild instanceof self )
		{
			$this->arrFolderChildren[$sFilename] = $aChild ;
		}
		
		// 文件
		else
		{
			$this->arrFileChildren[$sFilename] = $aChild ;
		}
	}
	
	/**
	 * Description
	 *
	 * @access	public
	 * @param	$sFilename
	 * @return	void
	 */
	public function Remove($sFilename)
	{
		unset($this->arrChildren[ $sFilename ]) ;
		unset($this->arrFolderChildren[ $sFilename ]) ;
		unset($this->arrFileChildren[ $sFilename ]) ;
	}
	
	/**
	 * Description
	 *
	 * @access	public
	 * @return	void
	 */
	public function RemoveRecursion(array $arrPath)
	{
		$sName = array_shift($arrPath) ;
		
		if(!count($arrPath))
		{
			$this->Remove($sName) ;
		}
		
		else
		{
			$aChild = $this->GetChild($sName) ;
			if( $aChild and ($aChild instanceof self) )
			{
				$aChild->RemoveRecursion($arrPath) ;
			}
		}
	}
	
	


	/**
	 * Description
	 *
	 * @access	public
	 * @param	$sToFolder
	 * @param	$hPackage										handle
	 * @param	$nReleaseFlg=JCAT_FSPackage::RELEASE_DEFAULT	int
	 * @return	void
	 */
	public function Release($sToFolder,$hPackage,$nOffset,$nReleaseFlg=JCAT_FSPackage::RELEASE_DEFAULT) 
	{
		if(!file_exists($sToFolder))
		{
			if( mkdir($sToFolder) )
			{
				chmod($sToFolder,0777) ;
			}
		}

		if( !is_dir($sToFolder) or !is_writable($sToFolder) )
		{
			throw new JCAT_Exception(JCAT_Language::SentenceEx(
				'输入的路径必须做为目录存在并可以写入：%s', 'JCAT', null, $sToFolder
			)) ;
		}
		
		$sPath = $sToFolder.'/'.$this->GetName() ;
		if( !file_exists($sPath) )
		{
			mkdir($sPath) ;
		}
		chmod($sPath,0777) ;
		
		// 子目录
		foreach( $this->arrFolderChildren as $aFolder )
		{
			$aFolder->Release($sPath,$hPackage,$nOffset,$nReleaseFlg) ;
		}
	
		// 子文件
		foreach( $this->arrFileChildren as $aFile )
		{
			$aFile->Release($sPath,$hPackage,$nOffset,$nReleaseFlg) ;
		}
	}
	
	
	/**
	 * Description
	 * 
	 * @access	private
	 * @var		array
	 */
	private $arrChildren = array() ;
	
	/**
	 * Description
	 * 
	 * @access	private
	 * @var		array
	 */
	private $arrFileChildren = array() ;
	
	/**
	 * Description
	 * 
	 * @access	private
	 * @var		array
	 */
	private $arrFolderChildren = array() ;

}
?>